﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web.Http;
using System.Threading.Tasks;
using System.Net.Http;
using System.Web.Http.Controllers;
using System.Threading;
using System.Web;
using StripeOne.ShortenUrl.Model;
using StripeOne.Core.Tools;

namespace StripeOne.ShortenUrl.API.Common
{
    public class ShortenApiController : ApiController
    {
        protected int Count;
        protected int Offset { get; private set; }
        protected int Limit { get; private set; }
        
        public override Task<HttpResponseMessage> ExecuteAsync(HttpControllerContext controllerContext, CancellationToken cancellationToken)
        {
            //ValidateSignature(controllerContext);
            GetPaging(controllerContext);
            return base.ExecuteAsync(controllerContext, cancellationToken);
        }

        protected ShortenApiResult<T> Run<T>(Func<T> runner)
        {
            try
            {
                var content = runner();

                var result = new ShortenApiResult<T>
                {
                    Content = content,
                    StatusCode = StatusCode.OK,
                    StatusMessage = "SUCCESS"
                };

                return result;
            }
            catch (ApiErrorException ex)
            {
                return ErrorResult<T>(ex);
            }
        }

        protected ShortenApiResult<T> RunWithPaging<T>(Func<T> runner)
        {
            try
            {
                var content =  runner();
                    
                var result = new ShortenApiResult<T>
                {
                    Content = content,
                    StatusCode = StatusCode.OK,
                    StatusMessage = "SUCCESS",
                    Paging = new Paging
                    {
                        Count = Count,
                        Limit = Limit,
                        Offset = Offset
                    }
                };

                return result;
            }
            catch (ApiErrorException ex)
            {
                return ErrorResult<T>(ex);
            }
        }

        protected static ShortenApiResult<T> ErrorResult<T>(ApiErrorException ex)
        {
            var result = new ShortenApiResult<T> { StatusCode = ex.StatusCode, StatusMessage = ex.Message };
            return result;
        }

        private void GetPaging(HttpControllerContext controllerContext)
        {
            try
            {
                if (controllerContext.Request.Method == HttpMethod.Get)
                {
                    var querystring = HttpUtility.ParseQueryString(controllerContext.Request.RequestUri.Query);
                    Offset = Parser.ToInt32(querystring.Get("offset"));
                    Limit = Parser.ToInt32(querystring.Get("limit"));
                }
                else
                {
                    var request = ShortenClassSerializer.Deserialize<IDictionary<string, object>>(controllerContext.Request.Content.ReadAsStringAsync().Result);
                    Offset = Parser.ToInt32(request["offset"].ToString());
                    Limit = Parser.ToInt32(request["limit"].ToString());
                }

                if (Limit <= 0 || Limit > 20) Limit = 20;
            }
            catch (Exception ex)
            {
                Offset = 0;
                Limit = 20;
            }
        }

        /*
        private void ValidateSignature(HttpControllerContext controllerContext)
        {
            if (!_config.ValidateSignature) return;

            try
            {
                //var consumerKey = _config.ConsumerKey;
                var consumerSecret = _config.ConsumerSecret;

                var sign = new OAuthSigner(consumerSecret);

                var col = new NameValueCollection();

                string timestamp;

                if (controllerContext.Request.Method == HttpMethod.Post || controllerContext.Request.Method == HttpMethod.Put || controllerContext.Request.Method == HttpMethod.Delete)
                {
                    var request = ImxClassSerializer.Deserialize<IDictionary<string, object>>(controllerContext.Request.Content.ReadAsStringAsync().Result);
                    timestamp = request["oauth_timestamp"].ToString();
                    foreach (var val in request)
                    {
                        col.Add(val.Key, val.Value.ToString());
                    }
                }
                else
                {
                    col = HttpUtility.ParseQueryString(controllerContext.Request.RequestUri.Query);
                    timestamp = col["oauth_timestamp"].ToString(CultureInfo.InvariantCulture);
                }

                var req = new OAuthRequest(controllerContext.Request.RequestUri.AbsoluteUri, col, controllerContext.Request.Method.Method);

                if (!sign.ValidateRequest(req))
                {
                    throw new InvalidSignatureException();
                }

                if (!sign.ValidateTimestamp(req, Convert.ToInt64(timestamp), _config.SignatureMaxDifference))
                {
                    throw new InvalidTimestampException();
                }
            }
            catch (Exception ex)
            {
                MibLog.Default.Exception(ex);
                throw;
            }
        }
         */
    }
}
